package com.siun.dk.module;

import static com.sirun.ble.constants.BleConfig.CMD_TYPE_FIND_CAR;
import static com.sirun.ble.constants.BleConfig.CMD_TYPE_LOCK;
import static com.sirun.ble.constants.BleConfig.CMD_TYPE_UNLOCK;
import static com.sirun.ble.constants.BleConfig.TAG_CONNECTED;
import static com.sirun.ble.constants.BleConfig.TAG_CONNECTED_AUTH;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import android.view.View;

import com.aw.baselib.base.AwBaseBindingActivity;
import com.aw.baselib.base.AwBaseEvent;
import com.aw.baselib.interfaces.IPermissionListener;
import com.aw.baselib.net.api.Okhttp3Manager;
import com.aw.baselib.util.AwDataUtil;
import com.aw.baselib.util.AwRecyclerViewUtil;
import com.aw.baselib.util.AwRxPermissionUtil;
import com.aw.baselib.util.AwThirdAppJudgeUtil;
import com.aw.baselib.util.AwVersionUtil;
import com.aw.baselib.util.IntentUtil;
import com.sirun.ble.bean.BleRssiBean;
import com.sirun.ble.constants.BleConfig;
import com.sirun.ble.listeners.OnBleConnectListener;
import com.sirun.ble.listeners.OnBleControlListener;
import com.sirun.ble.listeners.OnBleRssiListener;
import com.sirun.ble.listeners.OnBleSystemStatusListener;
import com.sirun.ble.manager.BleManager;
import com.sirun.ble.utils.AwDateUtil;
import com.sirun.ble.utils.AwLog;
import com.sirun.ble.utils.sdk.AwBleUtil;
import com.siun.dk.base.MyApp;
import com.siun.dk.constants.MyConstant;
import com.siun.dk.events.EventRefreshBleNameType;
import com.siun.dk.events.EventRefreshBleStatusType;
import com.siun.dk.events.EventRefreshRssiType;
import com.siun.wuling.R;
import com.siun.wuling.databinding.ActivityMainBinding;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AwBaseBindingActivity<ActivityMainBinding> {

    private static final int REQUEST_CODE_OPEN_GPS = 0;
    private static final int REQUEST_CODE_OPEN_LOCATION = 1;
    private BluetoothDevice mBluetoothDevice;
    private List<String> mHintList = new ArrayList<>();
    private HintAdapter mAdapter;
    private Disposable mDisposableInfo;
    private int mRssi = 0;
    private boolean isScanning = false;
    private BleRssiBean mBleRssiBean;
    private Handler mHandle = new Handler();

    @Override
    public void refreshByBus(AwBaseEvent type) {
        super.refreshByBus(type);
        if(type instanceof EventRefreshBleNameType) {
            if(BleManager.getInstance().isBleConnected()) {
                BleManager.getInstance().closeConnect();
                showConnectStatus(false);
                mHandle.postDelayed(() -> toConnect(), 1000);
            } else {
                toConnect();
            }
        }
    }

    @Override
    protected ActivityMainBinding getViewBinding() {
        return ActivityMainBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void initView() {
        super.initView();
    }

    @Override
    protected void initData() {
        super.initData();
        setText(binding.tvVersion, AwVersionUtil.getVersion(mActivity));
        mAdapter = new HintAdapter();
        AwRecyclerViewUtil.setRecyclerViewLinearlayout(mActivity, binding.rcvData, mAdapter, false);
        mAdapter.addAllData(mHintList);
        BleManager.getInstance().setDebug(true);

        toConnect();
    }

    @Override
    protected void initListener() {
        super.initListener();
        binding.llBleStatus.setOnClickListener(v -> {
            if(BleManager.getInstance().isBleConnected()) {
                showDialogCustomLeftAndRight("确定要断开蓝牙连接吗？", "取消", "确定", null, v1 -> {
                    mBluetoothDevice = null;
                    BleManager.getInstance().closeConnect();
                    showConnectStatus(false);
                });
            } else {
                if(isScanning) {
                    showMsg("正在扫描连接中, 请勿重复操作...");
                    return;
                }
                toConnect();
            }
        });
        binding.tvSetting.setOnClickListener(v -> {
            toClass(SettingActivity.class, false);
        });
        binding.tvRecord.setOnClickListener(v -> {
            if(isShow(binding.rcvData)) {
                showView(binding.rcvData, false);
            } else {
                showView(binding.rcvData, true);
            }
        });
        binding.tvCalibration.setOnClickListener(v -> {
            if(!BleManager.getInstance().isBleConnected()) {
                showMsg("请先连接蓝牙");
                return;
            }
            toClass(CalibrationActivity.class, false);
        });
        binding.llUnlock.setOnClickListener(v -> {
            if(!BleManager.getInstance().isBleConnected()) {
                showMsg("请先连接蓝牙");
                return;
            }
            addHint("执行解锁");
            BleManager.getInstance().controlCarByBle(BleConfig.CMD_TYPE_UNLOCK);
        });
        binding.llLock.setOnClickListener(v -> {
            if(!BleManager.getInstance().isBleConnected()) {
                showMsg("请先连接蓝牙");
                return;
            }
            BleManager.getInstance().controlCarByBle(BleConfig.CMD_TYPE_LOCK);
        });
    }

    private void toConnect() {
        if(AwDataUtil.isEmpty(BleManager.getInstance().getBleName())) {
            showDialogCustomLeftAndRight("请先到设置页面，配置蓝牙名称后连接", "取消", "确定", null, v -> toClass(SettingActivity.class, false));
            return;
        }
        if(MyApp.getInstance().isBleInitSuccess) {
            toStart();
            toRegisterBleListener();
        } else {
            mHandle.postDelayed(() -> {
                toStart();
                toRegisterBleListener();
            }, 2000);
        }
    }

    private void loopInfo() {
        AwLog.d(TAG, "****** loopInfo ******");
        if(BleManager.getInstance().isBleConnected()) {
            mDisposableInfo = Observable.interval(10, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(aLong -> {
                        //TODO 啥也不做. 这里逻辑待用
                    });
        }
    }

    private void cancelLoopInfo() {
        if(mDisposableInfo != null) {
            AwLog.d(TAG, "****** cancelLoopInfo ******");
            mDisposableInfo.dispose();
        }
    }

    private void startLoopInfo() {
        cancelLoopInfo();
        AwLog.d(TAG, "****** startLoopInfo ******");
        loopInfo();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelLoopInfo();
        if(mHandle != null) {
            mHandle.removeCallbacksAndMessages(null);
            mHandle = null;
        }
    }

    private void toRegisterBleListener() {
        BleManager.getInstance().setBleSystemStatusListener(new OnBleSystemStatusListener() {
            @Override
            public void bleOpen() {
                isScanning = false;
                toStart();
            }

            @Override
            public void bleClose() {
                postEvent(new EventRefreshBleStatusType(false));
                isScanning = false;
                showConnectStatus(false);
            }
        });
        BleManager.getInstance().setBleConnectListener(new OnBleConnectListener() {
            @Override
            public void connected(BluetoothDevice device, int code) {
                postEvent(new EventRefreshBleStatusType(false));
                isScanning = false;
                showMsg("连接成功");
                showConnectStatus(true);
                addHint("连接成功");
                mBluetoothDevice = device;
                if(device != null) {
                    AwLog.d("监听 setBleConnectListener connected getName: " + mBluetoothDevice.getName() + " ,getAddress: " + mBluetoothDevice.getAddress() + " ,code: " + code);
                } else {
                    AwLog.d("监听 setBleConnectListener connected device is null, code: " + code);
                }

                dismissLoadingDialog();
//                startLoopInfo();
//                if(code == TAG_CONNECTED_AUTH || code == TAG_CONNECTED) {
//                    setText(binding.tvConnectStatus, "连接状态: 已连接");
//                    setText(binding.tvToConnect, "断开连接");
//                    if(mBluetoothDevice != null) {
//                        setText(binding.tvDeviceName, "设备名称: " + mBluetoothDevice.getName());
//                        setText(binding.tvDeviceMAC, "设备MAC: " + mBluetoothDevice.getAddress());
//                    }
//                }
            }

            @Override
            public void connectFail(BluetoothDevice device, int code, String result) {
                postEvent(new EventRefreshBleStatusType(false));
                isScanning = false;
                showMsg("连接失败");
                showConnectStatus(false);

                mBluetoothDevice = null;
                addHint("连接失败, code: " + code + " ,result: " + result);
                dismissLoadingDialog();
//                setText(binding.tvConnectStatus, "连接状态: 未连接");
//                setText(binding.tvToConnect, "去连接");
//                if(device != null) {
//                    setText(binding.tvDeviceName, "设备名称: --");
//                    setText(binding.tvDeviceMAC, "设备MAC: --");
//                }

            }
        });

        BleManager.getInstance().setBleRssiListener(new OnBleRssiListener() {
            @Override
            public void getRssiBean(BleRssiBean rssiBean) {
                mBleRssiBean = rssiBean;
            }

            @Override
            public void getRssi(int rssi) {
                postEvent(new EventRefreshRssiType(rssi));
                mRssi = rssi;
                AwLog.d("监听  setBleRssiListener getRssi: " + (-rssi));
//                setText(binding.tvRssi, "RSSI: " + rssi);
                addHint("执行上报RSSI, rssi: " + (-rssi));

                if(MyConstant.BASE_URL.equals("http://")) {
                    AwLog.d("服务器地址未配置，取消上报");
                    return;
                }
                String url = MyConstant.BASE_URL + "/linkpower?rssis=" + (-rssi);
                Okhttp3Manager.getRequest(url, new Okhttp3Manager.OkhttpCallback() {
                    @Override
                    public void onSuccess(String str) {
                        addHint("执行上报RSSI, 成功");
                    }

                    @Override
                    public void onFail(String msg) {
                        addHint("执行上报RSSI, 失败, msg: " + msg);
                    }
                });
            }

            @Override
            public void getRssiEvery(String data) {

//                mHintList.add(data);
//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        binding.rcvData.scrollToPosition(mHintList.size() - 1);
//                    }
//                });

                AwLog.d("监听  setBleRssiListener getRssiEvery: " + data + " ,size: " + mHintList.size());
            }
        });

        BleManager.getInstance().setBleControlListener(new OnBleControlListener() {
            @Override
            public void controlFail(int type, int code, String msg) {
                AwLog.d("===>setBleControlListener controlFail");
                dismissLoadingDialog();
                switch (type) {
                    case CMD_TYPE_LOCK:
                        showMsg("关锁失败");
                        addHint("闭锁结果: " + msg);
                        break;
                    case CMD_TYPE_UNLOCK:
                        showMsg("解锁失败");
                        addHint("开锁结果: " + msg);
                        break;
                    case CMD_TYPE_FIND_CAR:
                        showMsg("寻车失败");
                        addHint("寻车结果: " + msg);
                        break;
                }
            }

            @Override
            public void sendCmdSuccess(int type) {
                AwLog.d("===>setBleControlListener sendCmdSuccess");
                addHint("指令已发送");
            }

            @Override
            public void underControl() {
                AwLog.d("===>setBleControlListener underControl");
                addHint("蓝牙控制执行中...");
            }

            @Override
            public void controlSuccess(int type) {
                AwLog.d("===>setBleControlListener controlSuccess");
                addHint("蓝牙控制执行成功");
                dismissLoadingDialog();
            }
        });

    }

    private void showConnectStatus(boolean isConnected) {
        if(isConnected) {
            runOnUiThread(() -> {
                binding.ivBleStatus.setImageDrawable(getDrawable(R.drawable.icon_ble_status_connected));
                setText(binding.tvBleStatus, "蓝牙已连接");
                binding.tvBleStatus.setTextColor(getResources().getColor(R.color.teal_700));
            });
        } else {
            runOnUiThread(() -> {
                binding.ivBleStatus.setImageDrawable(getDrawable(R.drawable.icon_ble_status_unconnect));
                setText(binding.tvBleStatus, "蓝牙未连接");
                binding.tvBleStatus.setTextColor(getResources().getColor(com.aw.baselib.R.color.color_A5A5A5));
            });
        }
    }

    private void addHint(String msg) {
        mHintList.add(msg);
        runOnUiThread(() -> binding.rcvData.scrollToPosition(mHintList.size() - 1));
    }

    private void toStart() {
        addHint("开始连接, 前置检测...");
        //应先检测权限
        checkBleStep1();
        BleManager.getInstance().startConnect();
    }

    /**
     * 蓝牙检测第1步 手机系统是否支持蓝牙
     */
    private void checkBleStep1() {
        if (!AwBleUtil.checkBleIsSupport(mActivity) || !AwBleUtil.isSupportBlue(mActivity)) {
            showDialog("当前设备不支持蓝牙",null);
            return;
        }
        checkBleStep2();
    }

    /**
     * 蓝牙检测第2步 手机系统蓝牙是否打开
     */
    private void checkBleStep2() {
        if (AwBleUtil.checkBleDevice(mActivity) == BleConfig.TAG_BLE_CLOSE) {
            showDialogWithCancelDismiss("系统蓝牙未打开", v -> {
                AwThirdAppJudgeUtil.toBleSetting(mActivity);
            });
            return;
        }
        checkBleStep3();
    }

    /**
     * 蓝牙检测第3步 是否已获取定位权限
     */
    private void checkBleStep3() {
        AwRxPermissionUtil.getInstance().checkPermissions(mActivity, AwRxPermissionUtil.getBluetoothPermissions(), new IPermissionListener() {
            @Override
            public void granted() {
                if(Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
                    if (!AwBleUtil.checkGPSIsOpen(mActivity)) {
                        showDialogWithCancelDismiss("请开启手机相关权限信息", v -> {
                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
                        });
                    }
                }
                checkBleStep4();
            }

            @Override
            public void shouldShowRequestPermissionRationale() {
                showDialogWithCancelDismiss("请开启手机相关权限信息，APP才可正常使用", v -> AwThirdAppJudgeUtil.toAppSysSetting(mActivity));
            }

            @Override
            public void needToSetting() {
                showDialogWithCancelDismiss("已禁止权限，请开启手机相关权限信息，APP才可正常使用",  v -> AwThirdAppJudgeUtil.toAppSysSetting(mActivity));
            }
        });
    }

    /**
     * 蓝牙检测第4步 是否打开系统定位开关
     */
    private void checkBleStep4() {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
            if (!isLocServiceEnable()) {
                showDialogWithCancelDismiss("蓝牙功能需要定位功能，请打开手机GPS定位", v -> IntentUtil.toLocationSetting(mActivity, REQUEST_CODE_OPEN_LOCATION));
                return;
            }
        }
        checkBleStep5();
    }

    /**
     * 蓝牙检测第5步 是否已连接蓝牙
     * 1, 未连接执行扫描并自动连接操作并在连接成功后发送相应车控指令;
     * 2, 已连接则直接进行相应车控指令
     * 同时监听写入回调
     */
    private void checkBleStep5() {
        //如果未连接, 自动发起蓝牙连接.
        AwLog.d("蓝牙连接状态: " + BleManager.getInstance().getConnectStatus());
        if (BleManager.getInstance().getConnectStatus() == BleConfig.TAG_CONNECTED_NONE) {
            AwLog.d("******** 连接蓝牙 ********");
            showLoadingDialogWithMsg("蓝牙连接中，请稍候...");
            showMsg("蓝牙连接中，请稍候...");
            addHint("蓝牙连接中，请稍候...");
            isScanning = true;
            BleManager.getInstance().startConnect();
            AwLog.d("执行扫描连接");
        } else {
//            showMsg("已连接...");
        }
    }

    /**
     * 手机定位开关是否开启
     *
     * @return
     */
    private boolean isLocServiceEnable() {
        LocationManager locationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return true;
        }
        return false;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CODE_OPEN_GPS:
                if (resultCode == RESULT_OK) {
                    checkBleStep4();
                } else {
                }
                break;
            case REQUEST_CODE_OPEN_LOCATION:
                if (resultCode == RESULT_OK) {
                    checkBleStep5();
                } else {
                }
                break;
        }
    }

    private void printBuildInfo() {
        StringBuffer sb = new StringBuffer();
        sb.append("设备基板名称: ").append(Build.BOARD).append("\n")
                .append("设备品牌: " + Build.BRAND).append("\n")
                .append("设备引导程序版本号: " + Build.BOOTLOADER).append("\n")
                .append("设备指令集名称: " + Build.CPU_ABI).append("\n")
                .append("设备指令集名称2: " + Build.CPU_ABI2).append("\n")
                .append("设备驱动名称: " + Build.DEVICE).append("\n")
                .append("设备显示的版本号: " + Build.DISPLAY).append("\n")
                .append("设备唯一标识（多个信息拼接组成）: " + Build.FINGERPRINT).append("\n")
                .append("设备硬件名称: " + Build.HARDWARE).append("\n")
                .append("设备主机地址: " + Build.HOST).append("\n")
                .append("设备版本号: " + Build.ID).append("\n")
                .append("设备型号: " + Build.MODEL).append("\n")
                .append("设备制造商: " + Build.MANUFACTURER).append("\n")
                .append("整个产品名称: " + Build.PRODUCT).append("\n")
                .append("无线电固件版本号: " + Build.RADIO).append("\n")
                .append("设备标签: " + Build.TAGS).append("\n")
                .append("时间: " + Build.TIME).append("\n")
                .append("时间（转换）: " + AwDateUtil.formatDate(new Date(Build.TIME), AwDateUtil.FORMAT_YMD_HMS)).append("\n")
                .append("设备版本类型: " + Build.TYPE).append("\n")
                .append("设备用户名: " + Build.USER).append("\n")
                .append("系统版本字符串: " + Build.VERSION.RELEASE).append("\n")
                .append("当前系统开发代号: " + Build.VERSION.CODENAME).append("\n")
                .append("系统源代码控制值: " + Build.VERSION.INCREMENTAL).append("\n")
                .append("系统API级别: " + Build.VERSION.SDK).append("\n")
                .append("系统API级别（数字表示）: " + Build.VERSION.SDK_INT);
        AwLog.d("===>BuildInfo: " + sb);
    }
}